/**
 * 文件名: src/app/api/route.ts
 * 
 * 文件概述:
 * API路由处理器，提供章节管理和AI请求的统一接口(仅网页版使用)。
 * 增强AI请求处理，支持多文件参考上下文。
 * 
 * 依赖项:
 * - next/server: { NextRequest, NextResponse } - Next.js API路由工具
 * - ../../../utils/platform: 平台工具函数(getChapters, saveChapter)
 * 
 * 类型定义:
 * - ApiResponse<T> = { data?: T; error?: string; }
 * - AiRequest = { prompt: string; context?: string; }
 * 
 * 导出函数:
 * - GET: (request: NextRequest) => Promise<NextResponse>
 * - POST: (request: NextRequest) => Promise<NextResponse>
 * 
 * 请求处理路径:
 * 1. GET请求:
 *    - /api?type=chapters: 获取章节列表
 *      - 调用platform.getChapters()
 *      - 返回章节数据
 * 
 * 2. POST请求:
 *    - /api?type=chapters: 保存章节
 *      - 从请求体获取chapter数据
 *      - 调用platform.saveChapter(chapter)
 *      - 返回成功/失败状态
 *    
 *    - /api?type=ai: 处理AI请求
 *      - 从请求体获取{prompt, context}
 *      - context包含当前章节和参考文件内容
 *      - 估算请求token数量，过大时返回错误
 *      - 获取OpenAI API密钥
 *      - 构建优化的系统提示和用户提示
 *      - 调用OpenAI API
 *      - 返回AI响应
 * 
 * OpenAI API调用增强:
 * - 系统提示: 根据上下文优化，告知AI处理参考内容的方式
 * - 用户提示格式: 结构化提供参考内容和用户请求
 * - token管理: 估算并控制请求大小，防止超出模型限制
 * 
 * AI请求处理函数:
 * async function handleAIRequest(req: NextRequest) {
 *   // 提取prompt和context
 *   // 检查token数量
 *   // 构建优化的AI请求
 *   // 处理响应
 * }
 * 
 * 错误处理:
 * - 使用try/catch捕获所有错误
 * - 返回统一格式{error: "message"}和适当的HTTP状态码
 * - 特殊处理token超限错误，提供明确提示
 * - 处理API限流、超时等特殊情况
 * 
 * 安全考虑:
 * - 验证请求参数完整性
 * - 保护API密钥(仅在服务器端使用)
 * - 添加基本请求速率限制
 * 
 * 注意事项:
 * - 仅网页版使用此API路由
 * - 桌面版直接使用platform.ts调用Tauri命令
 * - 确保错误响应格式一致
 * - 优化大文本处理，考虑压缩或摘要
 */

import { NextRequest, NextResponse } from 'next/server';
import { getChapters, saveChapter, estimateTokens } from '../../utils/platform';
import { Chapter } from '../../store';

// API响应类型
type ApiResponse<T> = {
  data?: T;
  error?: string;
};

// AI请求类型
type AiRequest = {
  prompt: string;
  context?: string;
};

// 速率限制追踪
const rateLimits = new Map<string, { count: number; timestamp: number }>();

// 清理过期的速率限制记录
const cleanupRateLimits = () => {
  const now = Date.now();
  for (const [ip, data] of rateLimits.entries()) {
    if (now - data.timestamp > 60 * 1000) { // 1分钟过期
      rateLimits.delete(ip);
    }
  }
};

// 每分钟清理一次
setInterval(cleanupRateLimits, 60 * 1000);

// 检查请求速率限制
const checkRateLimit = (ip: string): boolean => {
  const now = Date.now();
  const limit = rateLimits.get(ip);
  
  if (!limit) {
    rateLimits.set(ip, { count: 1, timestamp: now });
    return true;
  }
  
  // 如果是旧记录，重置
  if (now - limit.timestamp > 60 * 1000) {
    rateLimits.set(ip, { count: 1, timestamp: now });
    return true;
  }
  
  // 更新计数
  limit.count += 1;
  
  // 检查是否超出限制
  return limit.count <= 10; // 每分钟最多10个请求
};

/**
 * 处理AI请求
 * @param req 请求对象
 * @returns API响应
 */
async function handleAIRequest(req: NextRequest): Promise<ApiResponse<string>> {
  try {
    // 提取请求内容
    const { prompt, context } = await req.json() as AiRequest;
    
    // 验证请求参数
    if (!prompt || typeof prompt !== 'string') {
      return { error: '无效的prompt参数' };
    }
    
    // 估算token数量
    const totalTokens = estimateTokens(prompt) + estimateTokens(context || '');
    if (totalTokens > 4000) {
      return { error: '提示和上下文内容过长，请减少文本或分割请求' };
    }
    
    // 获取OpenAI API密钥
    const apiKey = process.env.OPENAI_API_KEY;
    if (!apiKey) {
      return { error: 'OpenAI API密钥未配置' };
    }
    
    // 构建系统提示
    const systemPrompt = context 
      ? '你是一位写作助手。我会给你一些参考资料，请在回答问题时充分利用这些资料提供有帮助的建议。如果参考资料中包含当前正在编写的章节，重点关注这部分内容。保持回答简洁、友好且富有创意。'
      : '你是一位写作助手。请提供简洁、友好且富有创意的写作建议。';
    
    // 构建用户提示
    let userPrompt = prompt;
    if (context) {
      userPrompt = `参考资料：\n${context}\n\n我的问题：${prompt}`;
    }
    
    // 调用OpenAI API
    const openaiResponse = await fetch('https://api.openai.com/v1/chat/completions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${apiKey}`
      },
      body: JSON.stringify({
        model: 'gpt-3.5-turbo',
        messages: [
          { role: 'system', content: systemPrompt },
          { role: 'user', content: userPrompt }
        ],
        temperature: 0.7
      })
    });
    
    // 检查响应状态
    if (!openaiResponse.ok) {
      const errorData = await openaiResponse.json();
      // 特殊处理API限流
      if (openaiResponse.status === 429) {
        return { error: 'API请求过于频繁，请稍后重试' };
      }
      return { error: `OpenAI API错误: ${errorData.error?.message || '未知错误'}` };
    }
    
    // 处理正常响应
    const data = await openaiResponse.json();
    const aiResponse = data.choices[0]?.message?.content?.trim();
    
    if (!aiResponse) {
      return { error: 'AI未返回有效响应' };
    }
    
    return { data: aiResponse };
  } catch (error: unknown) {
    // 异常处理
    const errorMessage = error instanceof Error ? error.message : String(error);
    return { error: `AI处理失败: ${errorMessage}` };
  }
}

/**
 * 处理GET请求
 * @param request 请求对象
 * @returns 响应对象
 */
export async function GET(request: NextRequest): Promise<NextResponse> {
  try {
    // 获取客户端IP
    const ip = request.headers.get('x-forwarded-for') || 'unknown';
    
    // 检查速率限制
    if (!checkRateLimit(ip)) {
      return NextResponse.json(
        { error: '请求频率过高，请稍后再试' },
        { status: 429 }
      );
    }
    
    // 解析查询参数
    const type = request.nextUrl.searchParams.get('type');
    
    if (type === 'chapters') {
      // 获取章节列表
      const result = await getChapters();
      
      if (result.error) {
        return NextResponse.json(
          { error: result.error },
          { status: 500 }
        );
      }
      
      return NextResponse.json({ data: result.data });
    }
    
    // 未知的请求类型
    return NextResponse.json(
      { error: '未知的请求类型' },
      { status: 400 }
    );
  } catch (error: unknown) {
    const errorMessage = error instanceof Error ? error.message : String(error);
    return NextResponse.json(
      { error: `请求处理失败: ${errorMessage}` },
      { status: 500 }
    );
  }
}

/**
 * 处理POST请求
 * @param request 请求对象
 * @returns 响应对象
 */
export async function POST(request: NextRequest): Promise<NextResponse> {
  try {
    // 获取客户端IP
    const ip = request.headers.get('x-forwarded-for') || 'unknown';
    
    // 检查速率限制
    if (!checkRateLimit(ip)) {
      return NextResponse.json(
        { error: '请求频率过高，请稍后再试' },
        { status: 429 }
      );
    }
    
    // 解析查询参数
    const type = request.nextUrl.searchParams.get('type');
    
    // 处理不同类型的请求
    if (type === 'chapters') {
      // 保存章节
      try {
        const chapter = await request.json() as Chapter;
        
        // 验证章节数据
        if (!chapter || !chapter.id || !chapter.title) {
          return NextResponse.json(
            { error: '无效的章节数据' },
            { status: 400 }
          );
        }
        
        // 保存章节
        const result = await saveChapter(chapter);
        
        if (result.error) {
          return NextResponse.json(
            { error: result.error },
            { status: 500 }
          );
        }
        
        return NextResponse.json({ data: true });
      } catch (parseError) {
        return NextResponse.json(
          { error: '无效的请求数据' },
          { status: 400 }
        );
      }
    } else if (type === 'ai') {
      // 处理AI请求
      const result = await handleAIRequest(request);
      
      if (result.error) {
        // 对token超限错误进行特殊处理
        if (result.error.includes('过长') || result.error.includes('token')) {
          return NextResponse.json(
            { error: result.error },
            { status: 413 } // 内容过大
          );
        }
        
        // 处理API限流错误
        if (result.error.includes('频繁') || result.error.includes('限流')) {
          return NextResponse.json(
            { error: result.error },
            { status: 429 } // 请求过多
          );
        }
        
        return NextResponse.json(
          { error: result.error },
          { status: 500 }
        );
      }
      
      return NextResponse.json({ data: result.data });
    }
    
    // 未知的请求类型
    return NextResponse.json(
      { error: '未知的请求类型' },
      { status: 400 }
    );
  } catch (error: unknown) {
    const errorMessage = error instanceof Error ? error.message : String(error);
    return NextResponse.json(
      { error: `请求处理失败: ${errorMessage}` },
      { status: 500 }
    );
  }
}